// 同步 异步

// node 异步IO 非阻塞
// 在node中的定时器是一个全局函数，不需要require就能适用
// 同步：从上往下执行
// js单线程语言 同一时间做一个事；
// js碰到异步任务 把异步任务放在了事件循环的执行队列中

/**
 * @异步现象
 * 1. 定时器
 * 2. http请求
 * 3. 事件
 */

/*
  单线程序   执行对列
  ｜       ｜ 
  ｜       ｜
  ｜       ｜
*/

/**
 * 打电话的例子：
 * 
 * @fn 同步： 9:00 --- 21:00
 *  优点：返回结果的确定性
 *  确定：造成代码阻塞
 * 
 * @fn 异步： 9:00（短信）     21:00（短信） 
 *  优点：节约时间 效率很高，不阻塞
 *  缺点：返回结果的不确定性
 */

/**
 * @js为什么能这么执行
 * js 运行环境不是单线程 运行环境：浏览器 + node环境
 */


/**
 * @异步存在的问题
 * 1. 结果获取的不确定性
 * 2. 可读性不够
*/

/**
 * @异步解决方案
 * 1. 回调函数 （）
 * 2. promise
 * 3. * 函数
 * 4. async await 函数 -> 终极解决方案
 */

 // 高阶函数： 用函数去操作函数的函数
 // 回调函数：一个函数， 作为参数， 传递到其他函数中，并且执行
function girlfn(fn) {
  setTimeout(() => {
    fn && fn(1) // 函数执行的时候，把实际参数 传递 给形式参数
  }, 3000)
}

girlfn((res) => {
  console.log(res, 'res--callback')
})

function proFn() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('hello world')
    }, 3000)
  })
}

proFn().then(res => {
  console.log(res, 'res--promise')
})

 async function boyFn() {
    const data = await proFn()
    console.log(data, 'async')
 }
 boyFn()




 /**
  * @fn 回调模式函数：
  * 
  * 定义：1个函数 作为参数 传递到其他函数中，并且执行
  * 
*/

/**
 * @异步代码演示区域借用fs读取文件演示
 */  

/**
 * @fn 第一种 回调函数模式 ： callback hell
 * 
 * 确定： 回调地狱，不利于维护
*/

const fs = require('fs')

fs.readFile('./work/data1.json', (err, data) => {
  const path1 = JSON.parse(data.toString()).name
  fs.readFile(path1, (err, data) => {
    const path2 = JSON.parse(data.toString()).name
    fs.readFile(path2, (err, data) => {
      // console.log(JSON.parse(data.toString()).name, 'data2')
    })
  })
})



function readFn(src) {
  return new Promise((resolve, reject) => {
    fs.readFile(src, (err, data) => {
      resolve(JSON.parse(data.toString()).name)
    })
  })
}

// readFn('./work/data1.json')
//   .then(res => {
//     console.log(res, 'res---res')
//     return readFn(res)
//   })
//   .then(res => {
//     console.log(res, 'res')
//     return readFn(res)
//   })
//   .then(res => {
//     console.log(res, 'res')
//   })


// resolve  reject pedding
 async function readFnSync() {
   const data = await readFn('./work/data1.json')
   const data1 = await readFn(data)
   const data2 = await readFn(data1)
  //  console.log(data, data1, data2)
   return {data ,  data1,  data2}
 }
// 凡是能用then方法的，肯定返回的是一个promise对象
 readFnSync()
   .then(res => {
    //  console.log(res, 'res')
   })


/**
 * @fn async await 异步函数 异步解决的终极方案
 *  
 * 作用：以同步的方式运行异步代码
 * 
 * 1. await后面可以跟promise函数
 * 2. await必须包含在async函数中
 * 3. async执行返回也是promise对象
 * 4. try-catch截获promise中的reject的值
 *
 * */   



